package eteam.aps.systemservice.common;

import eteam.aps.common.R;
import eteam.aps.common.exceptions.AuthException;
import eteam.aps.common.exceptions.BusinessException;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;

@ControllerAdvice
public class SystemServiceGlobalExceptionHandler {
    /**
     * 系统抛出的未处理过异常
     *
     * @param request: Http请求
     * @param e:       异常消息
     * @return: 返回接口数据
     * @return: 返回接口数据
     */
    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public R defaultErrorHandler(HttpServletRequest request, Exception e) {
        return R.failed(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage());
    }

    /**
     * 未授权/授权无效，异常处理
     *
     * @param request: Http请求
     * @param e:       异常消息
     * @throws Exception
     * @return: 返回接口数据
     */
    @ResponseBody
    @ExceptionHandler(value = AuthException.class)
    public R authErrorHandler(HttpServletRequest request, AuthException e) {
        return R.failed(HttpStatus.UNAUTHORIZED.value(), e.getMessage());
    }

    /**
     * 业务逻辑，异常处理
     *
     * @param request: Http请求
     * @param e:       异常消息
     * @throws Exception
     * @return: 返回接口数据
     */
    @ResponseBody
    @ExceptionHandler(value = BusinessException.class)
    public R businessErrorHandler(HttpServletRequest request, BusinessException e) {
        return R.failed(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage());
    }

    /**
     * 参数绑定不合法，异常处理
     *
     * @param request
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = BindException.class)
    public R bindErrorHandler(HttpServletRequest request, BindException e) {
        List msgs = new ArrayList<String>();
        for (ObjectError be : e.getAllErrors()) {
            msgs.add(be.getDefaultMessage());
        }
        return R.failed(HttpStatus.PRECONDITION_FAILED.value(), String.join("|", msgs));
    }

    /**
     * 参数验证不合法，异常处理
     *
     * @param request
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public R methodArgumentErrorHandler(HttpServletRequest request, MethodArgumentNotValidException e) {
        List msgs = new ArrayList<String>();
        for (ObjectError be : e.getBindingResult().getAllErrors()) {
            msgs.add(be.getDefaultMessage());
        }
        return R.failed(HttpStatus.PRECONDITION_FAILED.value(), String.join("|", msgs));
    }

    /**
     * 数据库，异常处理
     *
     * @param request: Http请求
     * @param e:       异常消息
     * @throws Exception
     * @return: 返回接口数据
     */
    @ResponseBody
    @ExceptionHandler(value = DataAccessException.class)
    public R dataAccessErrorHandler(HttpServletRequest request, DataAccessException e) {
        return R.failed(HttpStatus.INTERNAL_SERVER_ERROR.value(), "数据库操作失败");
    }

    /**
     * 数据库，异常处理
     *
     * @param request: Http请求
     * @param e:       异常消息
     * @throws Exception
     * @return: 返回接口数据
     */
    @ResponseBody
    @ExceptionHandler(value = DuplicateKeyException.class)
    public R duplicateKeyErrorHandler(HttpServletRequest request, DuplicateKeyException e) {
        return R.failed(HttpStatus.INTERNAL_SERVER_ERROR.value(), "数据库已存在重复数据");
    }
}
